/*
 * NunchukManager.cpp
 *
 *  Created on: 06/lug/2011
 *      Author: marcolembo
 */

#ifndef _WP_
#define _WP_
#include "WProgram.h"
#endif

#include "NunchukMidiManager.h"

namespace ml
{
	NunchukMidiManager::NunchukMidiManager(short joyX_CC,
	                                       short joyY_CC
	                                       ) {

	    //strategies--di default sono tutti controller
	   m_strategies = new MidiCcStrategy[6];


		for(short i=0; i<2; i++)
			joystick[i] = 0;
		for(short i=0; i<2; i++)
			oldJoystick[i] = 0;

		joystickCC[0] = joyX_CC;
		joystickCC[1] = joyY_CC;

		for(short i=0; i<3; i++)
			accel[i] = 0;
		for(short i=0; i<3; i++)
			oldAccel[i] = 0;
		for(short i=0; i<2; i++)
			button[i] = 0;
		for(short i=0; i<2; i++)
			oldButton[i] = 0;

		accelCC[0] = 7;
		accelCC[1] = 9;
		accelCC[2] = 10;

		buttonNote[0] = 36;
		buttonNote[1] = 38;

		//inizializzazione dell'oggetto nunchuk
		m_nunchukDrv.initialize();
	}

	//inizializzazione puntatore singleton
	NunchukMidiManager* NunchukMidiManager::nunMidiManager = NULL;


	NunchukMidiManager* NunchukMidiManager::GetInstance(short joyX_CC, short joyY_CC)
	{
		if(!nunMidiManager)
		{
			nunMidiManager = new NunchukMidiManager(joyX_CC, joyY_CC);
		}
		return nunMidiManager;
	}

	//imposta la strategia selezionata nel parametro corrispondente fornito in input
    void NunchukMidiManager::SetStrategy(MidiStrategy *str, enParameters par)
    {
        MidiStrategy* tmpStr = &m_strategies[par];
        delete tmpStr;
        tmpStr = str;
    }


	NunchukMidiManager::~NunchukMidiManager() {
	    delete[] m_strategies;
	    delete nunMidiManager;
	}

	//Nunchuk UTILS methods
	void NunchukMidiManager::ParseData()
	{
		joystick[0] = m_nunchukDrv.joystick_x();
		joystick[1] = m_nunchukDrv.joystick_y();
		accel[0] = m_nunchukDrv.x_acceleration();
		accel[1] = m_nunchukDrv.y_acceleration();
		accel[2] = m_nunchukDrv.z_acceleration();

		if(m_nunchukDrv.z_button())
			button[0] = 1;
		else
			button[0] = 0;
		if(m_nunchukDrv.c_button())
			button[1] = 1;
		else
			button[1] = 0;
	}


	void NunchukMidiManager::SendMidi(short canaleMidi)
	{
	  for (short i = 0; i < 2; i++) {
		if (abs(oldJoystick[i] - joystick[i]) >= 2) {
		  MIDI.sendControlChange(joystickCC[i], map(joystick[i], 0, 255, 0, 127), canaleMidi);
		  oldJoystick[i] = joystick[i];
		}
	  }

	  for (short i = 0; i < 3; i++) {
		if (abs(oldAccel[i] - accel[i]) >= 7) {
		  int value = map(accel[i], 300, 800, 0, 127);
		  MIDI.sendControlChange(accelCC[i], constrain(value, 0, 127), canaleMidi);
		  oldAccel[i] = accel[i];
		}
	  }

	  for (short i = 0; i < 2; i++) {
		if (oldButton[i] != button[i]) {
		  if (button[i] == 0)
		  {
			MIDI.sendNoteOn(buttonNote[i], 100, canaleMidi);
		  }
		  else
		  {
			MIDI.sendNoteOff(buttonNote[i], 0, canaleMidi);
		  }
		  oldButton[i] = button[i];
		}
	  }
	} //end SendMidi

	bool NunchukMidiManager::Update()
	{
	    return(m_nunchukDrv.update());
	}
}

